#version 450

in vec3 fragPos;
in vec2 fragUv;
in flat vec2 fragTexIdx;
in flat uint fragAnimSize;
in float fragLighting;

uniform sampler2D uTexture;
uniform sampler2D uOpaqueDepth;
uniform float zFar = 500.0f;
uniform float zNear = 0.1f;
uniform float uFrame;

layout(location = 0) out vec4 accumTexture;
layout(location = 1) out vec4 revealageTexture;

float d(float z) {
    return ((zNear * zFar) / z - zFar) / (zNear - zFar);
}

float weight(float z, float a) {
    float b = 1 - d(z);
    return a * max(0.01f, b * b * b * 0.003);
}

void main() {
    if (gl_FragCoord.z > texelFetch(uOpaqueDepth, ivec2(gl_FragCoord.xy), 0).r + 0.000005){
        discard;
    }

    float texSize = textureSize(uTexture, 0).x;
    float texTileSize = texSize / 16.0;
    uint frame = uint(int(uFrame)) % fragAnimSize;

    vec2 animIdx = fragTexIdx + vec2(frame, 0);
    animIdx.y += float(int(animIdx.x) / int(texTileSize));
    animIdx.x = float(int(animIdx.x) % int(texTileSize));

    vec2 uvIdx = fragUv + animIdx;
    vec2 uv = uvIdx * 16.0 / textureSize(uTexture, 0);
    vec4 color = texture(uTexture, uv);
    if (color.a == 1) discard; // opaque objects are already drawn
    accumTexture = vec4(color.xyz, color.w) * weight(gl_FragCoord.z, color.w);
    revealageTexture = vec4(color.w);
}